package rpc.provider.impl;

import lombok.extern.slf4j.Slf4j;
import rpc.config.RpcServiceConfig;
import rpc.enums.RpcErrorMessageEnum;
import rpc.exceprion.RpcException;
import rpc.extension.ExtensionLoader;

import rpc.provider.ServiceProvider;
import rpc.registry.ServiceRegistry;
import rpc.remote.transport.netty.server.NettyRpcServer;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @ClassName: ZkServiceProviderImpl
 * @Description: Zookeeper支持功能、添加服务、寻找服务、发布服务等
 * @author: Kowk
 * @since:1.0.0
 */
@Slf4j
public class ZkServiceProviderImpl implements ServiceProvider {

    /**
    * @Description: key是rpc服务的名称（interfaceName+version+group） ；value是服务实体
    * @Param:
    * @return:
    */
    private final Map<String,Object> serviceMap;
    private final Set<String> registeredService;
    private final ServiceRegistry serviceRegistry;

    public ZkServiceProviderImpl(){
        serviceMap = new ConcurrentHashMap<>();
        registeredService = ConcurrentHashMap.newKeySet();
        serviceRegistry = (ServiceRegistry) ExtensionLoader.getExtensionLoader(ServiceRegistry.class).getExtension("zk");
    }

    @Override
    public void addService(RpcServiceConfig rpcServiceConfig) {
        String rpcServiceName = rpcServiceConfig.getRpcServiceName();
        if(registeredService.contains(rpcServiceName)){
            return;
        }
        registeredService.add(rpcServiceName);
        serviceMap.put(rpcServiceName,rpcServiceConfig.getService());
        log.info("添加服务：{} 和接口{}",rpcServiceName,rpcServiceConfig.getService().getClass().getInterfaces());
    }

    @Override
    public Object getService(String rpcServiceName) {
        Object service = serviceMap.get(rpcServiceName);
        if (service == null) {
            throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_FOUND);
        }
        return service;
    }

    @Override
    public void publishService(RpcServiceConfig rpcServiceConfig) {
        try {
            String host = InetAddress.getLocalHost().getHostAddress();
            this.addService(rpcServiceConfig);
            serviceRegistry.registerService(rpcServiceConfig.getRpcServiceName(),new InetSocketAddress(host, NettyRpcServer.PORT));
        } catch (UnknownHostException e) {
            log.error("在getHostAddress时发生错误",e);
        }
    }
}
